package GMDPRE

import (
	"fmt"
)

func BytesToBn(bn *BN, digs int, bytes []uint8, bytesLen int) int {
	if bytesLen > digs*4 {
		return -1
	}

	var tmp DigT = 0
	var i = bytesLen - 1
	var j = 0
	var k = 0
	for i >= 0 {
		tmp = tmp | (DigT(bytes[i]) << (j * 8))
		j = (j + 1) & 0b11
		if j == 0 {
			bn[k] = tmp
			k++
			tmp = 0
		}

		i--
	}

	if j == 0 && k < digs {
		bn[k] = tmp
		k++
	}

	for k < digs {
		bn[k] = 0
		k++
	}

	return 0
}

func BnToBytes(bn *BN, digs int) []uint8 {
	var bytes = make([]uint8, digs*4)
	var i = digs - 1
	var j = 0
	for i >= 0 {
		bytes[j*4] = uint8((bn[i] >> 24) & 0xff)
		bytes[j*4+1] = uint8((bn[i] >> 16) & 0xff)
		bytes[j*4+2] = uint8((bn[i] >> 8) & 0xff)
		bytes[j*4+3] = uint8(bn[i] & 0xff)
		i--
		j++
	}
	return bytes
}

func BytesEqual(bytes1 []uint8, bytes2 []uint8, bytesLen int) int {
	if len(bytes1) != bytesLen || len(bytes2) != bytesLen || len(bytes1) != len(bytes2) {
		return 0
	}

	i := 0
	for i < bytesLen {
		if bytes1[i] != bytes2[i] {
			return 0
		}
		i++
	}

	return 1
}

func BnEqual(bn1 *BN, bn2 *BN, digs int) int {
	i := 0
	for i < digs {
		if bn1[i] != bn2[i] {
			return 0
		}
		i++
	}

	return 1
}

func lower(hex uint8) uint8 {
	if hex <= 57 && hex >= 48 {
		return hex - 48
	}
	if hex <= 70 && hex >= 65 {
		return 10 + hex - 65
	}
	if hex <= 102 && hex >= 97 {
		return 10 + hex - 97
	}
	return 255
}

func HexToBytes(hex string) []uint8 {
	var bytes []uint8
	var i int
	var bh, bl uint8

	if len(hex) == 0 {
		return []uint8{}
	}

	i = 0
	if len(hex)&1 == 1 {
		bl = lower(hex[0])
		if bl == 255 {
			return []uint8{}
		}
		bytes = append(bytes, bl)
		i = 1
	}

	for i < len(hex) {
		bh = lower(hex[i])
		bl = lower(hex[i+1])
		if bh == 255 || bl == 255 {
			return []uint8{}
		}
		bytes = append(bytes, (bh<<4)|bl)
		i += 2
	}

	return bytes
}

func GetRandomBytes(bytesLen int) []uint8 {
	var tmp uint32
	var res []uint8

	i := 0
	j := 0
	for i < bytesLen {
		if j == 0 {
			tmp = sysRand.Uint32()
		}

		res = append(res, uint8(tmp>>(j*8)&0xff))

		j = (j + 1) & 0b11
		i++
	}

	return res
}

func down4bytes(n uint32) []uint8 {
	res := make([]uint8, 4)
	res[0] = uint8((n >> 24) & 0xff)
	res[1] = uint8((n >> 16) & 0xff)
	res[2] = uint8((n >> 8) & 0xff)
	res[3] = uint8(n & 0xff)
	return res
}

func TestGetRandom() {
	for i := 0; i < 32; i++ {
		fmt.Println(GetRandomBytes(32))
	}
}
